package com.alks.function.service.impl.stockdept.pcfactorystockquery;

import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.dto.SysUserTokenDTO;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.service.RedisService;
import com.alks.common.utils.beanutils.ArrayUtils;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.entity.data.entity.*;
import com.alks.entity.data.enums.SlipDeptEnum;
import com.alks.entity.data.enums.SlipTypeEnum;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.InDataException;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.dto.pcfactorywork.PcSupplementDetailDto;
import com.alks.function.data.dto.pcfactorywork.PcSupplementMtlDto;
import com.alks.function.data.dto.pcfactorywork.PcSupplementSizeDto;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.DutyFileDto;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.SpHeadDto;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.SpPartDto;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.SpPartSubDto;
import com.alks.function.data.request.stockdept.pcfactorystockwork.*;
import com.alks.function.data.vo.controller.stockdept.UsageToSuppVo;
import com.alks.function.mapper.chengKong.PcLotHeadMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.*;
import com.alks.function.service.SdPositionService;
import com.alks.function.service.stockdept.pcfactorystockquery.IPcSubWorkService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import jodd.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.support.atomic.RedisAtomicInteger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.alks.entity.data.enums.RedisFormatEnum.BF_BL_LENGTH;
import static com.alks.entity.data.enums.ResultCodeEnum.*;

@Service
@Slf4j
@RequiredArgsConstructor
public class PcSubWorkServiceImpl extends ServiceImpl<SD_SQ_PcSupplementHeadMapper, PcSupplementHead> implements IPcSubWorkService {
    private final SD_SQ_PcSupplementHeadMapper headMapper;
    private final SD_SQ_SdBomPartNew2Mapper partMapper;
    private final SD_SQ_PcSupplementDetailMapper detailMapper;
    private final SD_SQ_SuppMtlTempMapper tempMapper;
    private final SD_SQ_PcSupplementSizeMapper sizeMapper;
    private final SD_SQ_PcLotUsageMapper usageMapper;
    private final SD_SQ_PcLotDetailMapper lotDetailMapper;
    private final SD_SQ_PcSupplementMtlMapper mtlMapper;
    private final SD_SQ_PcSupplementDutyTempMapper dTempMapper;
    private final SD_SQ_PcSupplementDutyTemp3Mapper dTemp3Mapper;
    private final SD_SQ_PcSupplementMtlLotMapper mtlLotMapper;
    private final SD_SQ_PcSupplementDutyMapper dutyMapper;
    private final PcLotHeadMapper lotMapper;
    private final SdPositionService vendorMapper;
    private final RedisService redis;

    private final String Y = "Y";

    @Override
    @AutoPageAop
    public ResponseInfo getSpHeadQuery(SpHeadRequest request) {
        /*获取数据*/
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String userName = tokenDTO.getUserName();
        String companyId = tokenDTO.getCompanyId();
        List<SpHeadDto> dtos = headMapper.getSpHeadQuery(request, userName,companyId);
        Page<SpHeadDto> page = (Page<SpHeadDto>) dtos;
        /*处理开补类型*/
        for (SpHeadDto dto : dtos) {
            dto.setBlFlag(SlipTypeEnum.SlipNameFind(dto.getBlFlag()));
        }
        /*封装结果*/
        Map<String, Object> map = new HashMap<>(2);
        map.put("dtos", dtos);
        map.put("total", page.getTotal());
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo getSpPartQuery(String lotNo) {
        /*获取数据*/
        List<SpPartDto> dtos = usageMapper.getSpPartQuery(lotNo);
        List<Map<String, Object>> size = lotDetailMapper.getSpPartSize(lotNo);
        List<String> slipType = SlipTypeEnum.SlipNameList();
        List<Map<String, String>> slipDept = SlipDeptEnum.slipDeptList();
        /*封装数据*/
        Map<String, Object> map = new HashMap<>(4);
        map.put("dtos", dtos);
        map.put("size", size);
        map.put("slipType", slipType);
        map.put("slipDept", slipDept);
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo getSpPartSubQuery(SpPartSubRequest request) {
        /*获取当前用户数据*/
        String userName = UserIdThread.get().getUserName();
        request.setSysUser(userName);
        /*获取数据*/
        List<SpPartSubDto> dtos = tempMapper.getSpPartOne(request);
        System.out.println(request.getSysUser());
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo getSpPartAppQuery(String lotNo, String slipNo) {
        /*获取已存在数据*/
        List<String> size = sizeMapper.getSpPartAppSize(lotNo, slipNo);
        List<String> seqNo = detailMapper.getSpPartAppSeq(lotNo, slipNo);
        String blFlag = headMapper.getSpPartAppBl(slipNo);
        /*没有数据则返回空*/
        if (seqNo == null || seqNo.isEmpty()) {
            return ResponseInfo.ok();
        }
        /*获取开补类型*/
        blFlag = SlipTypeEnum.SlipTypeFind(blFlag);
        log.error("blflag:{}", blFlag);
        /*封装数据*/
        Map<String, Object> map = new HashMap<>();
        map.put("size", size);
        map.put("seqNo", seqNo);
        map.put("blFlag", blFlag);
        return ResponseInfo.ok(map);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseInfo spPartAdd(SpPartRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        /*判断是否有该指令*/
        LambdaQueryWrapper<PcLotHead> wrapper = new LambdaQueryWrapper<PcLotHead>()
                .eq(PcLotHead::getLotNo, request.getLotNo())
                .eq(PcLotHead::getCompanyId, companyId)
                .last("LIMIT 1");
        PcLotHead lotHead = lotMapper.selectOne(wrapper);
        if (BeanUtil.isEmpty(lotHead)) {
            return ResponseInfo.error("未查询到该指令");
        }
        if (!Y.equals(lotHead.getCheckFlag())) {
            return ResponseInfo.error("指令未审核");
        }
        /*判断入参是否合法*/
        if (BeanUtil.allIsEmpty(request) || request.getSeqNo().isEmpty()) {
            return ResponseInfo.error("请选择开补部位");
        }
        if(ArrayUtils.isEmpyt(request.getSize())){
            return ResponseInfo.error("请选择号码");
        }
        if (request.getSlipDeptName().isEmpty()) {
            return ResponseInfo.error("请选择补料部门");
        }
        if (request.getBlFlag().isEmpty()) {
            return ResponseInfo.error("请选择补料类型");
        }
        /*获取初始数据*/
        List<UsageToSuppVo> usage = usageMapper.getPartAddQuery(request,companyId);
        if (usage.isEmpty()) {
            log.error("请求方法：spPartAdd\n对应表：SD_BOM_PART_NEW2\n原因：没有找到对应数据\nlotNo：{}||seqNo{}：",
                    request.getLotNo(), request.getSeqNo());
            return ResponseInfo.error("数据异常，请联系管理员");
        }
        List<PcSupplementDetail> details = BeanUtil.copyList(usage, PcSupplementDetail.class);
        List<PcSupplementSize> sizes = BeanUtil.copyList(usage, PcSupplementSize.class);
        /*获取需要拓展的数据*/
        String userName = UserIdThread.get().getUserName();
        LocalDate now = LocalDate.now();
        String blFlag = SlipTypeEnum.SlipTypeFind(request.getBlFlag());
        String slipNo = null;
        if (request.getSlipNo().isEmpty()) {
            String dept = request.getSlipDeptNo().substring(2, 4);
            String date = now.format(DateTimeFormatter.ofPattern("yyMM"));
            String key = companyId + "BL" + date + dept;
            RedisAtomicInteger ato = new RedisAtomicInteger(key, redis.getConnectionFactory());
            int increment = ato.getAndIncrement();
            String num = String.format("%0" + BF_BL_LENGTH.getValue() + "d", increment);
            redis.setOutTime(key);
            slipNo = key + num;
        }
        /*写入尺寸序号*/
        List<String> sortedSizes = request.getSize().stream().sorted().collect(Collectors.toList());
        Map<String, Integer> sizeMap = new HashMap<>();
        int seq = 1;
        for (String s : sortedSizes) {
            if (sizeMap.put(s, seq) == null) {
                seq++;
            }
        }
        System.out.println(sizeMap.get("41") + "\n" + sizeMap.get("39") + "\n" + sizeMap.get("40"));
        /*进行数据补充*/
        List<PcSupplementSize> sizes2 = new ArrayList<>();
        /*如果是首次添加的数据则写入head表中*/
        if (request.getSlipNo().isEmpty()) {
            PcSupplementHead head = new PcSupplementHead();
            head.setSysUser(userName);
            head.setSysDate(LocalDateTime.now());
            head.setSlipDate(now);
            head.setBlFlag(blFlag);
            head.setDutyDeptName(request.getSlipDeptName());
            head.setDutyDeptNo(request.getSlipDeptNo());
            head.setCompanyId(usage.get(0).getCompanyId());
            head.setSlipNo(request.getSlipNo().isEmpty() ? slipNo : request.getSlipNo());
            headMapper.insert(head);
        }
        int seqNo = 0;
        for (int i = 0; i < usage.size(); i++) {
            /*如果没有补料单号则为新增*/
            details.get(i).setSlipNo(request.getSlipNo().isEmpty() ? slipNo : request.getSlipNo());
            sizes.get(i).setCompanyId(usage.get(i).getCompanyId());
            sizes.get(i).setLotNo(request.getLotNo());
            sizes.get(i).setSlipNo(request.getSlipNo().isEmpty() ? slipNo : request.getSlipNo());
            for (String size : request.getSize()) {
                PcSupplementSize newSize = BeanUtil.copyBean(sizes.get(i), PcSupplementSize.class);
                newSize.setSizeNo(size);
                newSize.setSizeSeq(sizeMap.get(size));
                sizes2.add(newSize);
            }
        }
        /*写入数据*/
        detailMapper.spPartAdd(details);
        sizeMapper.spPartAdd(sizes2);
        return ResponseInfo.ok("新增成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseInfo spMtlAdd(String slipNo) {
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String companyId = tokenDTO.getCompanyId();
        String userName = tokenDTO.getUserName();
        /*判断入参正确性*/
        LambdaQueryWrapper<PcSupplementDetail> wrapper = new LambdaQueryWrapper<PcSupplementDetail>()
                .eq(PcSupplementDetail::getSlipNo, slipNo)
                .eq(PcSupplementDetail::getCompanyId, companyId);
        List<PcSupplementDetail> details = detailMapper.selectList(wrapper);
        if (details == null || BeanUtil.allIsEmpty(details)) {
            return ResponseInfo.error("开补部位没有数据，无法计算", INPUT_ERROR.getCode());
        }
        /*清除旧数据*/
        LambdaQueryWrapper<PcSupplementMtlLot> lWrapper = new LambdaQueryWrapper<PcSupplementMtlLot>()
                .eq(PcSupplementMtlLot::getSlipNo, slipNo)
                .eq(PcSupplementMtlLot::getCompanyId, companyId);
        mtlLotMapper.delete(lWrapper);
        LambdaQueryWrapper<PcSupplementMtl> mtlWrapper = new LambdaQueryWrapper<PcSupplementMtl>()
                .eq(PcSupplementMtl::getSlipNo, slipNo)
                .eq(PcSupplementMtl::getCompanyId, companyId);
        mtlMapper.delete(mtlWrapper);
        /*检验尺码起止的合法性*/
        List<PcSupplementSize> sizeList = sizeMapper.getSizeSeq(slipNo, companyId);
        Map<String, Integer> sizeMap = sizeList.stream().collect(Collectors.toMap(PcSupplementSize::getSizeNo, PcSupplementSize::getSizeSeq));
        // 获取非法数量
        for (PcSupplementDetail detail : details) {
            if (detail.getSize1() != null && detail.getSize2() != null) {
                Integer minSeq = sizeMap.get(detail.getSize1());
                Integer maxSeq = sizeMap.get(detail.getSize2());

                if (minSeq != null && maxSeq != null) {
                    // 检查lQty1到lQty24
                    for (int i = 1; i <= 20; i++) {
                        try {
                            Field lQtyField = PcSupplementDetail.class.getDeclaredField("lQty" + i);
                            Field rQtyField = PcSupplementDetail.class.getDeclaredField("rQty" + i);
                            lQtyField.setAccessible(true);
                            rQtyField.setAccessible(true);

                            Float lQtyValue = (Float) lQtyField.get(detail);
                            Float rQtyValue = (Float) rQtyField.get(detail);

                            // 如果对应序号不在指定范围内且值不为null，则抛出异常
                            boolean errFlag = (lQtyValue != null || rQtyValue != null) && (i < minSeq || i > maxSeq);
                            if (errFlag) {
                                throw new ServiceErrorException("请在指定号码段内输入");
                            }
                        } catch (NoSuchFieldException | IllegalAccessException e) {
                            log.error("检验尺码起止合法性时发生异常", e);
                            throw new ServiceErrorException("服务异常");
                        }
                    }
                }
            }
        }
        /*获取需要添加的数据*/
        mtlMapper.spMtlAdd(slipNo, companyId, userName);
        mtlLotMapper.spMtlAdd(slipNo,companyId);
        return ResponseInfo.ok("计算完成");
    }

    @Override
    public ResponseInfo spDetailCopyUpdate(SpDetailCopyReqiest request) {
        String companyId = UserIdThread.get().getCompanyId();
        slipUpCheck(request.getSlipNo(), companyId);
        /*更新数据*/
        detailMapper.spDetailCopyUpdate(request);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo spPrintUpdate(String slipNo) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取打印需要的各部位对应材料组成*/
        List<String> mtlConcatList = detailMapper.spPrintQuery(slipNo,companyId);
        /*责任分配检核*/
        dutyCheck(slipNo, companyId);
        /*更新数据*/
        headMapper.spPrintUpdate(slipNo);
        return ResponseInfo.ok(mtlConcatList);
    }

    @Override
    public ResponseInfo spTurnCfmUpdate(String slipNo, Integer type) {
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String companyId = tokenDTO.getCompanyId();
        String userName = tokenDTO.getUserName();
        /*判断数据是否已打印*/
        LambdaQueryWrapper<PcSupplementHead> wrapper = new LambdaQueryWrapper<PcSupplementHead>()
                .eq(PcSupplementHead::getSlipNo, slipNo)
                .eq(PcSupplementHead::getCompanyId, companyId);
        PcSupplementHead head = headMapper.selectOne(wrapper);
        if (head==null){
            throw new ServiceErrorException("数据失效");
        }
        /*责任分配检核*/
        if (type.equals(1)) {
            dutyCheck(slipNo, companyId);
            if (!Y.equals(head.getPrnFlag())) {
                return ResponseInfo.error("请先打印");
            }
        }else if (type.equals(0)){
            if (Y.equals(head.getFinanceFlag())) {
                return ResponseInfo.error("已审核,无法取消");
            }
        }
        /*更新数据*/
        headMapper.spTurnCfmUpdate(slipNo,type, userName, companyId);
        return ResponseInfo.ok("转审核成功");
    }


    @Override
    public ResponseInfo getDutyFileQuery(Integer type) {
        /*获取数据*/
        List<DutyFileDto> dtos = new ArrayList<>();
        String userName = UserIdThread.get().getUserName();
        switch (type) {
            case 1: {
                dtos = dTemp3Mapper.getDutyFileQuery(userName);
                break;
            }
            case 2: {
                dtos = dTempMapper.getDutyFileQuery(userName);
                break;
            }
        }
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo getDutyFileAdd(List<DutyFileRequest> request, Integer type) {
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String userName = tokenDTO.getUserName();
        String companyId = tokenDTO.getCompanyId();
        LocalDateTime now = LocalDateTime.now();
        /*先判断是否有数据，有则报错*/
        switch (type) {
            case 1: {
                for (DutyFileRequest r : request) {
                    /*检测重复数据*/
                    LambdaQueryWrapper<PcSupplementDutyTemp3> temp3Wrapper = new LambdaQueryWrapper<PcSupplementDutyTemp3>()
                            .eq(PcSupplementDutyTemp3::getCompanyId, companyId)
                            .eq(PcSupplementDutyTemp3::getSysUser, userName)
                            .eq(StringUtils.isNotBlank(r.getIdNo()), PcSupplementDutyTemp3::getIdNo, r.getIdNo())
                            .eq(PcSupplementDutyTemp3::getDeptNo, r.getDeptNo());
                    if (dTemp3Mapper.selectCount(temp3Wrapper) > 0) {
                        return ResponseInfo.error("数据重复，请勿重复添加");
                    }
                }
                /*写入责任数据*/
                dTemp3Mapper.dutyFileAdd(request, userName, now, companyId);
                break;
            }
            case 2: {
                /*责任员工有ID*/
                List<DutyFileRequest> noIdEmployee = request.stream().filter(a -> StringUtils.isBlank(a.getIdNo())).collect(Collectors.toList());
                if (ArrayUtils.isNoEmpyt(noIdEmployee)) {
                    log.error("\n错误接口：getDutyFileAdd\n错误接口：责任员工无ID\n错误表：【PC_EMPLOYEE】 \n员工数据：{}", noIdEmployee);
                    return ResponseInfo.error("员工ID不能为空", INPUT_ERROR.getCode());
                }
                /*检测重复数据*/
                List<String> idList = request.stream().map(DutyFileRequest::getIdNo).collect(Collectors.toList());
                LambdaQueryWrapper<PcSupplementDutyTemp> wrapper = new LambdaQueryWrapper<PcSupplementDutyTemp>()
                        .eq(PcSupplementDutyTemp::getCompanyId, companyId)
                        .eq(PcSupplementDutyTemp::getSysUser, userName)
                        .in(PcSupplementDutyTemp::getIdNo, idList);
                if (dTempMapper.selectCount(wrapper) != 0) {
                    return ResponseInfo.error("存在责任方重复,请勿重复添加", INPUT_ERROR.getCode());
                }
                dTempMapper.dutyFileAdd(request, userName, now);
                break;
            }
            default:
                return ResponseInfo.error("参数错误", INPUT_ERROR.getCode());
        }
        return ResponseInfo.ok("更新完成");

    }

    @Override
    public ResponseInfo getDutyFileUpdate(List<DutyFileRequest> request, Integer type) {
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String userName = tokenDTO.getUserName();
        String companyId = tokenDTO.getCompanyId();
        BigDecimal maxPercent = BigDecimal.valueOf(100);
        /*先判断是否有数据，有则报错*/
        BigDecimal sum = request.stream().map(DutyFileRequest::getQty).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
        switch (type) {
            case 1: {
                LambdaQueryWrapper<PcSupplementDutyTemp3> percentWrapper = new LambdaQueryWrapper<PcSupplementDutyTemp3>()
                        .select(PcSupplementDutyTemp3::getDutyPercent)
                        .eq(PcSupplementDutyTemp3::getSysUser, userName)
                        .eq(PcSupplementDutyTemp3::getCompanyId, companyId);
//                BigDecimal percent = dTemp3Mapper.selectList(percentWrapper).stream()
//                        .map(PcSupplementDutyTemp3::getDutyPercent)
//                        .filter(Objects::nonNull)
//                        .reduceigDecimal.ZERO, BigDecimal::add);
//                /*判断比例是否大于100%*/
//                if (sum.add(percent).compareTo(maxPercent) > 0) {
//                    return ResponseInfo.error("目前责任占比总和超过100%，当前为：" + sum.add(percent) + "%，请调整至100%以内", INPUT_ERROR.getCode());
//                }
                LambdaQueryWrapper<PcSupplementDutyTemp3> wrapper = new LambdaQueryWrapper<PcSupplementDutyTemp3>()
                        .eq(PcSupplementDutyTemp3::getSysUser, userName)
                        .in(PcSupplementDutyTemp3::getDeptName, request.stream().map(DutyFileRequest::getDeptName).collect(Collectors.toList()))
                        .in(request.stream()
                                        .filter(Objects::nonNull)
                                        .map(DutyFileRequest::getIdNo)
                                        .filter(Objects::nonNull)
                                        .findAny().isPresent()
                                , PcSupplementDutyTemp3::getIdNo, request.stream().map(DutyFileRequest::getIdNo).collect(Collectors.toList()));
                if (dTemp3Mapper.selectCount(wrapper) == 0) {
                    return ResponseInfo.error("未找到责任方", DATA_IS_EMPTY.getCode());
                }
                dTemp3Mapper.dutyFileUpdate(request);
                break;
            }
            case 2: {
                LambdaQueryWrapper<PcSupplementDutyTemp> wrapper = new LambdaQueryWrapper<PcSupplementDutyTemp>()
                        .eq(PcSupplementDutyTemp::getSysUser, userName)
                        .in(PcSupplementDutyTemp::getDeptName, request.stream().map(DutyFileRequest::getDeptName).collect(Collectors.toList()))
                        .in(request.stream().map(DutyFileRequest::getIdNo).findAny().isPresent()
                                , PcSupplementDutyTemp::getIdNo, request.stream().map(DutyFileRequest::getIdNo).collect(Collectors.toList()));
                if (dTempMapper.selectCount(wrapper) == 0) {
                    log.error("请求方法：getDutyFileUpdate\n错误原因：数据库找不到对应员工\n请求参数：" +
                            "\nDeptName：" + request.stream().map(DutyFileRequest::getDeptName) +
                            "\nidNo：" + request.stream().map(DutyFileRequest::getIdNo));
                    return ResponseInfo.error("未找到此责任员工", DATA_IS_EMPTY.getCode());
                }
                dTempMapper.dutyFileUpdate(request);
            }
            default:
                break;
        }
        return ResponseInfo.ok("更新完成");
    }

    @Override
    @Transactional
    public ResponseInfo dutyFileAdd(DutyAddRequest request, BigDecimal qty, Integer type, Integer flag) {
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String companyId = tokenDTO.getCompanyId();
        String userName = tokenDTO.getUserName();
        /*存储最终分配数量*/
        List<PcSupplementDuty> dutyList = new ArrayList<>();
        if (flag.equals(1)){
            /*清空选择的物料 方便后续操作*/
            request.setMtlNo(null);
            /*全部分配*/
            dutyByAll(request, type,  dutyList);
        }else{
            /*单材料分配*/
            dutyByOne(request, qty, type, dutyList);
        }
        /*判断最终数据是否超出限制*/
        //key：物料 value：此次将会分配数量
        Map<String, BigDecimal> mtlQtyMap = dutyList.stream()
                .collect(Collectors.toMap(PcSupplementDuty::getMtlNo,
                        PcSupplementDuty::getDutyQty,
                        BigDecimal::add));
        /*获取责任数据还可以分配的数量*/
        List<Map<String,Object>> pendingList = mtlMapper.getPendingQty(request.getSlipNo(),request.getMtlNo(), companyId);
        for (Map<String, Object> pending : pendingList) {
            String mtlNo = (String) pending.get("mtlNo");
            BigDecimal pendingQty = (BigDecimal) pending.get("qty");
            if (mtlQtyMap.get(mtlNo)!=null && mtlQtyMap.get(mtlNo).compareTo(pendingQty)>0) {
                throw new ServiceErrorException("物料：" + mtlNo + "分配数量超额，可分配数量为：" + pendingQty.stripTrailingZeros());
            }
        }
        /*写入责任数据*/
        for (PcSupplementDuty duty : dutyList) {
            dutyMapper.insert(duty);
        }
        return null;
    }

    /**
     * 处理全部材料统一分配情况
     */
    private void dutyByAll(DutyAddRequest request, Integer type,List<PcSupplementDuty> dutyList) {
        String userName = UserIdThread.get().getUserName();
        String companyId = UserIdThread.get().getCompanyId();
        request.setMtlNo(null);
        /*处理统一分配情况*/
        if (!type.equals(0)&&!type.equals(1)){
            log.warn("\n异常接口：dutyFileAdd\n异常原因：厂商是数量分配，不能全部材料统一处理");
            throw new InDataException("传参异常");
        }
        /*获取物料需求量数据*/
        LambdaQueryWrapper<PcSupplementMtl> mtlWrapper = new LambdaQueryWrapper<PcSupplementMtl>()
                .eq(PcSupplementMtl::getSlipNo, request.getSlipNo())
                .eq(PcSupplementMtl::getCompanyId, companyId);
        List<PcSupplementMtl> mtlList = mtlMapper.selectList(mtlWrapper);
        List<Map<String, Object>> mtlQtyList = mtlList.stream()
                .map(a -> {
                    Map<String, Object> map = new HashMap<>(2);
                    map.put("mtlNo", a.getMtlNo());
                    map.put("reqQty", new BigDecimal(a.getReqQty().toString()));
                    return map;
                })
                .collect(Collectors.toList());
        switch (type){
            case 0:
                vendorAndEmpDuty(request, userName, companyId, mtlQtyList, dutyList);
                break;
            case 1:
                empDuty(request, userName, companyId, mtlQtyList, dutyList);
                break;
            default:
                break;
        }
    }

    /**
     * 处理单一材料统一分配情况
     */
    private void dutyByOne(DutyAddRequest request, BigDecimal qty, Integer type,  List<PcSupplementDuty> dutyList) {
        String userName = UserIdThread.get().getUserName();
        String companyId = UserIdThread.get().getCompanyId();
        /*处理单条分配情况*/
        if (StringUtils.isBlank(request.getMtlNo())){
            throw new ServiceErrorException("请先选择要分配的材料");
        }
        LambdaQueryWrapper<PcSupplementMtl> mtlWrapper = new LambdaQueryWrapper<PcSupplementMtl>()
                .eq(PcSupplementMtl::getSlipNo, request.getSlipNo())
                .eq(PcSupplementMtl::getMtlNo, request.getMtlNo())
                .eq(PcSupplementMtl::getCompanyId, companyId);
        List<PcSupplementMtl> mtlList = mtlMapper.selectList(mtlWrapper);
        if (ArrayUtils.isEmpyt(mtlList)){
            throw new ServiceErrorException("未查询到该订单下此物料");
        }
        if (mtlList.size()>1){
            throw new ServiceErrorException("该订单下出现重复材料，请重新计算");
        }
        PcSupplementMtl mtl = mtlList.get(0);
        Map<String, Object> map = new HashMap<>(2);
        BigDecimal reqQty = new BigDecimal(mtl.getReqQty().toString());
        map.put("mtlNo", mtl.getMtlNo());
        map.put("reqQty", reqQty);
        List<Map<String, Object>> mtlQtyList = new ArrayList<>();
        mtlQtyList.add(map);
        switch (type){
            case 0:
                vendorAndEmpDuty(request, userName, companyId, mtlQtyList, dutyList);
                break;
            case 1:
                empDuty(request, userName, companyId, mtlQtyList, dutyList);
                break;
            case 2:
                if (qty.compareTo(reqQty)>0){
                    throw new ServiceErrorException("分配数量不能需求数量");
                }
                PcSupplementDuty duty = vendorDutyCreat(request.getSlipNo(), request.getVendorNo(), null, map);
                duty.setDutyQty(qty);
                dutyList.add(duty);
                break;
            default:
                break;
        }
    }


    /**
     * 部门类型责任数据写入
     */
    private PcSupplementDuty vendorDutyCreat(String slipNo, String vendorNo, String deptName, Map<String, Object> map) {
        String companyId = UserIdThread.get().getCompanyId();
        String userName = UserIdThread.get().getUserName();
        PcSupplementDuty duty = new PcSupplementDuty();
        // type = 0的时候直接传入vendorName||type = 3的时候去【SD_VENDOR】获取
        String vendorName = StringUtil.isBlank(deptName) ? vendorMapper.getNameByNo(vendorNo) : deptName;
        /*部门部分数据*/
        duty.setDutyName(vendorName);
        duty.setDutyVendorNo(vendorNo);
        duty.setCompanyId(companyId);
        duty.setSlipNo(slipNo);
        duty.setMtlNo((String) map.get("mtlNo"));
        duty.setSysUser(userName);
        duty.setSysDate(LocalDateTime.now());
        return duty;
    }

    private void empDuty(DutyAddRequest request, String userName, String companyId, List<Map<String, Object>> mtlQtyList, List<PcSupplementDuty> dutyList) {
        /*获取责任占比*/
        LambdaQueryWrapper<PcSupplementDutyTemp> tempWrapper = new LambdaQueryWrapper<PcSupplementDutyTemp>()
                .eq(PcSupplementDutyTemp::getSysUser, userName)
                .eq(PcSupplementDutyTemp::getCompanyId, companyId);
        List<PcSupplementDutyTemp> tempList = dTempMapper.selectList(tempWrapper);
        if (ArrayUtils.isEmpyt(tempList)){
            throw new ServiceErrorException("请先新增分配责任人");
        }
        if (Y.equals(tempList.get(0).getAveFlag())){
            /*平均分配处理*/
            int size = tempList.size();
            for (Map<String, Object> map : mtlQtyList) {
                BigDecimal reqQtySum = BigDecimal.ZERO;
                BigDecimal reqQty1 = (BigDecimal) map.get("reqQty");
                BigDecimal reqQty = (reqQty1).divide(new BigDecimal(size), 2, RoundingMode.HALF_UP);
                for (int i = 0; i < tempList.size(); i++) {
                    PcSupplementDutyTemp temp = tempList.get(i);
                    PcSupplementDuty duty = new PcSupplementDuty();
                    /*人员部分数据*/
                    duty.setDutyName2(temp.getName());
                    duty.setDeptNo(temp.getDeptNo());
                    duty.setDeptName(temp.getDeptName());
                    duty.setIdNo(temp.getIdNo());
                    duty.setCompanyId(companyId);
                    duty.setSlipNo(request.getSlipNo());
                    duty.setMtlNo((String) map.get("mtlNo"));
                    /*最后一次循环里补全处理*/
                    if (i == size - 1) {
                        duty.setDutyQty((reqQty1).subtract(reqQtySum));
                    }else{
                        duty.setDutyQty(reqQty);
                        reqQtySum = reqQtySum.add(reqQty);
                    }
                    duty.setDutyName(null);
                    dutyList.add(duty);
                }
            }
        }else{
            tempList = tempList.stream()
                    .filter(a->a.getDutyQty()!=null && a.getDutyQty().compareTo(BigDecimal.ZERO)>0)
                    .collect(Collectors.toList());
            for (Map<String, Object> map : mtlQtyList) {
                for (PcSupplementDutyTemp temp : tempList) {
                    PcSupplementDuty duty = vendorDutyCreat(request.getSlipNo(),temp.getDeptNo(),temp.getDeptName(), map);
                    duty.setDutyVendorNo(null);
                    duty.setDutyName2(temp.getName());
                    duty.setDeptNo(temp.getDeptNo());
                    duty.setDeptName(temp.getDeptName());
                    duty.setIdNo(temp.getIdNo());
                    duty.setDutyQty(((BigDecimal) map.get("reqQty")).multiply(temp.getDutyQty()).divide(new BigDecimal(100), 6, RoundingMode.HALF_UP));
                    duty.setDutyName(null);
                    dutyList.add(duty);
                }
            }
        }
    }

    private void vendorAndEmpDuty(DutyAddRequest request, String userName, String companyId, List<Map<String, Object>> mtlQtyList, List<PcSupplementDuty> dutyList) {
        /*获取责任占比*/
        LambdaQueryWrapper<PcSupplementDutyTemp3> temp3Wrapper = new LambdaQueryWrapper<PcSupplementDutyTemp3>()
                .eq(PcSupplementDutyTemp3::getSysUser, userName)
                .eq(PcSupplementDutyTemp3::getCompanyId, companyId);
        List<PcSupplementDutyTemp3> temp3List = dTemp3Mapper.selectList(temp3Wrapper);
        if (ArrayUtils.isEmpyt(temp3List)){
            throw new ServiceErrorException("请先新增分配责任人");
        }
        if (Y.equals(temp3List.get(0).getAveFlag())){
            /*平均分配处理*/
            int size = temp3List.size();
            for (Map<String, Object> map : mtlQtyList) {
                BigDecimal reqQtySum = BigDecimal.ZERO;
                BigDecimal reqQty = (BigDecimal) map.get("reqQty");
                //平均后分配量
                BigDecimal aveReqQty = (reqQty).divide(new BigDecimal(size), 2, RoundingMode.HALF_UP);
                for (int i = 0; i < temp3List.size(); i++) {
                    PcSupplementDutyTemp3 temp3 = temp3List.get(i);
                    PcSupplementDuty duty;
                    if (StringUtils.isBlank(temp3.getIdNo())) {
                        /*部门部分数据*/
                        duty = vendorDutyCreat(request.getSlipNo(),temp3.getDeptNo(),temp3.getDeptName(), map);
                    } else {
                        /*人员部分数据*/
                        //大部分逻辑相同，直接沿用后进行数据补充
                        duty = vendorDutyCreat(request.getSlipNo(),temp3.getDeptNo(),temp3.getDeptName(), map);
                        duty.setDutyVendorNo(null);
                        duty.setDutyName2(temp3.getName());
                        duty.setDeptNo(temp3.getDeptNo());
                        duty.setDeptName(temp3.getDeptName());
                        duty.setIdNo(temp3.getIdNo());
                        duty.setDutyName(null);
                    }
                    /*最后一次循环里补全处理*/
                    if (i == temp3List.size() - 1) {
                        duty.setDutyQty(reqQty.subtract(reqQtySum));
                    }else{
                        duty.setDutyQty(aveReqQty);
                        reqQtySum = reqQtySum.add(aveReqQty);
                    }
                    dutyList.add(duty);
                }
            }
        }else{
            temp3List = temp3List.stream()
                    .filter(a->a.getDutyPercent()!=null && a.getDutyPercent().compareTo(BigDecimal.ZERO)>0)
                    .collect(Collectors.toList());
            for (Map<String, Object> map : mtlQtyList) {
                for (PcSupplementDutyTemp3 temp3 : temp3List) {
                    PcSupplementDuty duty;
                    if (StringUtils.isBlank(temp3.getIdNo())) {
                        /*部门部分数据*/
                        duty = vendorDutyCreat(request.getSlipNo(),temp3.getDeptNo(),temp3.getDeptName(), map);
                    } else {
                        /*人员部分数据*/
                        //大部分逻辑相同，直接沿用后进行数据补充
                        duty = vendorDutyCreat(request.getSlipNo(),temp3.getDeptNo(),temp3.getDeptName(), map);
                        duty.setDutyName(null);
                        duty.setDutyName2(null);
                        duty.setDutyVendorNo(null);
                        duty.setDutyName2(temp3.getName());
                        duty.setDeptNo(temp3.getDeptNo());
                        duty.setDeptName(temp3.getDeptName());
                        duty.setIdNo(temp3.getIdNo());
                    }
                    duty.setDutyQty(((BigDecimal) map.get("reqQty")).multiply(temp3.getDutyPercent()).divide(new BigDecimal(100), 6, RoundingMode.HALF_UP));
                    dutyList.add(duty);
                }
            }
        }
    }

    @Override
    public ResponseInfo spDetailUpdate(List<SpDetailUpRequest> request, Integer sizeNum) {
        String companyId = UserIdThread.get().getCompanyId();
        for (SpDetailUpRequest detail : request) {
            slipUpCheck(detail.getSlipNo(),companyId);
        }
        /*判断是否输入了超额数据*/
        for (SpDetailUpRequest r : request) {
            for (int i = sizeNum + 1; i <= 20; i++) {
                /*通过反射循环检测每一项数据是否为空*/
                String lQtyFieldName = "lQty" + i;
                String rQtyFieldName = "rQty" + i;
                try {
                    Field lQtyField = SpDetailUpRequest.class.getDeclaredField(lQtyFieldName);
                    Field rQtyField = SpDetailUpRequest.class.getDeclaredField(rQtyFieldName);
                    lQtyField.setAccessible(true);
                    rQtyField.setAccessible(true);
                    Float lQtyValue = (Float) lQtyField.get(r);
                    Float rQtyValue = (Float) rQtyField.get(r);
                    if (lQtyValue != null || rQtyValue != null) {
                        return ResponseInfo.error("超出分段尺寸限制", INPUT_ERROR.getCode());
                    }
                } catch (NoSuchFieldException e) {
                    log.error("请求方法：spDetailUpdate\n错误原因：尺寸数量超出范围限制");
                    return ResponseInfo.error("服务异常", DATA_IS_ERR.getCode());
                } catch (IllegalAccessException e) {
                    log.error("请求方法：spDetailUpdate\n错误原因：请求参数异常");
                    return ResponseInfo.error("服务异常");
                }
            }
        }
        /*更新数据*/
        detailMapper.spDetailUpdate(request);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo spRemakrUpdate(String slipNo, String remark) {
        String companyId = UserIdThread.get().getCompanyId();
        slipUpCheck(slipNo,companyId);
        /*更新数据*/
        headMapper.spRemakrUpdate(slipNo, remark);
        return ResponseInfo.ok();
    }

    @Override
    public void parentComputer(Integer type) {
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String companyId = tokenDTO.getCompanyId();
        String userName = tokenDTO.getUserName();
        /*获取数据长度*/
        Integer size = 0;
        switch (type){
            case 0:
                LambdaQueryWrapper<PcSupplementDutyTemp3> temp3Wrapper = new LambdaQueryWrapper<PcSupplementDutyTemp3>()
                        .eq(PcSupplementDutyTemp3::getSysUser,userName)
                        .eq(PcSupplementDutyTemp3::getCompanyId, companyId);
                size = dTemp3Mapper.selectCount(temp3Wrapper);
                if (size<=0){
                    return;
                }
                break;
            case 1:
                LambdaUpdateWrapper<PcSupplementDutyTemp> tempWrapper = new LambdaUpdateWrapper<PcSupplementDutyTemp>()
                        .eq(PcSupplementDutyTemp::getSysUser,userName)
                        .eq(PcSupplementDutyTemp::getCompanyId, companyId);
                size = dTempMapper.selectCount(tempWrapper);
                if (size<=0){
                    return;
                }
                break;
            default:
                return;
        }
        /*避免精度丢失采用整数计算后取小数点算法*/
        BigDecimal total = BigDecimal.valueOf(100);
        //记录百分比
        BigDecimal percent = total.divide(BigDecimal.valueOf(size), 0, RoundingMode.HALF_UP);
        //防止百分比丢失
        BigDecimal percent2 = percent.subtract(BigDecimal.valueOf(size-1));
        switch (type){
            case 0:
                /*先进行数据分配，最后进行补余*/
                LambdaUpdateWrapper<PcSupplementDutyTemp3> temp3Wrapper = new LambdaUpdateWrapper<PcSupplementDutyTemp3>()
                        .set(PcSupplementDutyTemp3::getDutyPercent, percent)
                        .set(PcSupplementDutyTemp3::getAveFlag,"Y")
                        .eq(PcSupplementDutyTemp3::getSysUser,userName)
                        .eq(PcSupplementDutyTemp3::getCompanyId, companyId);
                dTemp3Mapper.update(null,temp3Wrapper);
                temp3Wrapper = new LambdaUpdateWrapper<PcSupplementDutyTemp3>()
                        .set(PcSupplementDutyTemp3::getDutyPercent, percent2)
                        .eq(PcSupplementDutyTemp3::getSysUser,userName)
                        .eq(PcSupplementDutyTemp3::getCompanyId, companyId)
                        .last("LIMIT 1");
                dTemp3Mapper.update(null,temp3Wrapper);
                break;
            case 1:
                /*先进行数据分配，最后进行补余*/
                LambdaUpdateWrapper<PcSupplementDutyTemp> tempWrapper = new LambdaUpdateWrapper<PcSupplementDutyTemp>()
                        .set(PcSupplementDutyTemp::getDutyQty, percent)
                        .set(PcSupplementDutyTemp::getAveFlag,"Y")
                        .eq(PcSupplementDutyTemp::getSysUser,userName)
                        .eq(PcSupplementDutyTemp::getCompanyId, companyId);
                dTempMapper.update(null,tempWrapper);
                tempWrapper = new LambdaUpdateWrapper<PcSupplementDutyTemp>()
                        .set(PcSupplementDutyTemp::getDutyQty, percent2)
                        .eq(PcSupplementDutyTemp::getSysUser,userName)
                        .eq(PcSupplementDutyTemp::getCompanyId, companyId)
                        .last("LIMIT 1");
                dTempMapper.update(null,tempWrapper);
                break;
            default:
                break;
        }


    }

    @Override
    @Transactional
    public ResponseInfo spAllDelete(String slipNo) {
        /*判断数据是否存在*/
        PcSupplementHead head = lambdaQuery().
                select(PcSupplementHead::getSlipNo, PcSupplementHead::getCfmFlag).
                eq(PcSupplementHead::getSlipNo, slipNo).one();
        if (BeanUtil.allIsEmpty(head)) {
            log.error("请求方法：spAllDelete\n错误原因：没有找到要删除的数据\n补料单号SlipNo：{}", slipNo);
            return ResponseInfo.error("未找到要删除的数据", DATA_IS_ERR.getCode());
        }
        if (head.getPrnFlag() != null && "Y".equals(head.getPrnFlag())) {
            return ResponseInfo.error("已打印，仅可作废处理");
        }
        /*删除全部表中数据*/
        detailMapper.spAllDelete(slipNo);
        sizeMapper.spAllDelete(slipNo);
        mtlMapper.spAllDelete(slipNo);
        mtlLotMapper.spAllDelete(slipNo);
        dutyMapper.spAllDelete(slipNo);
        headMapper.spAllDelete(slipNo);
        return ResponseInfo.ok("删除成功");
    }

    @Override
    public ResponseInfo getSpDetailQery(String slipNo) {
        /*判空*/
        if (slipNo.isEmpty()) {
            return ResponseInfo.error("订单号不能为空", LOGIN_CONFIG_IS_NULL.getCode());
        }
        List<PcSupplementMtlDto> mtl = mtlMapper.getSpMtlQuery(slipNo);
        /*查询细节数据*/
        LambdaQueryWrapper<PcSupplementDetail> dQueryWrapper = new LambdaQueryWrapper<PcSupplementDetail>()
                .eq(PcSupplementDetail::getCompanyId, UserIdThread.get().getCompanyId())
                .eq(PcSupplementDetail::getSlipNo, slipNo);
        List<PcSupplementDetail> details = detailMapper.selectList(dQueryWrapper);
        if (details == null || details.isEmpty()) {
            return ResponseInfo.ok(null);
        }
        /*封装数据*/
        Map<String, Object> map = new HashMap<>(2);
        /*提取拷贝*/
        List<PcSupplementDetailDto> dtos = BeanUtil.copyList(details, PcSupplementDetailDto.class);
        for (PcSupplementDetailDto dto : dtos) {
            dto.setTotal(getSumBy14Safely(dto));
        }
        map.put("detail", dtos);
        map.put("mtl", mtl);
        return ResponseInfo.ok(map);
    }

    /**
     * 获取14连打印的数据
     *
     * @param data 需要采集的数据
     * @return 求和
     */
    private BigDecimal getSumBy14Safely(PcSupplementDetailDto data) {
        BigDecimal total = BigDecimal.ZERO;
        // 对每个字段进行非空检查后累加
        total = safeAdd(total, data.getLQty1());
        total = safeAdd(total, data.getRQty1());
        total = safeAdd(total, data.getLQty2());
        total = safeAdd(total, data.getRQty2());
        total = safeAdd(total, data.getLQty3());
        total = safeAdd(total, data.getRQty3());
        total = safeAdd(total, data.getLQty4());
        total = safeAdd(total, data.getRQty4());
        total = safeAdd(total, data.getLQty5());
        total = safeAdd(total, data.getRQty5());
        total = safeAdd(total, data.getLQty6());
        total = safeAdd(total, data.getRQty6());
        total = safeAdd(total, data.getLQty7());
        total = safeAdd(total, data.getRQty7());
        total = safeAdd(total, data.getLQty8());
        total = safeAdd(total, data.getRQty8());
        total = safeAdd(total, data.getLQty9());
        total = safeAdd(total, data.getRQty9());
        total = safeAdd(total, data.getLQty10());
        total = safeAdd(total, data.getRQty10());
        total = safeAdd(total, data.getLQty11());
        total = safeAdd(total, data.getRQty11());
        total = safeAdd(total, data.getLQty12());
        total = safeAdd(total, data.getRQty12());
        total = safeAdd(total, data.getLQty13());
        total = safeAdd(total, data.getRQty13());
        total = safeAdd(total, data.getLQty14());
        total = safeAdd(total, data.getRQty14());
        total = total.divide(BigDecimal.valueOf(2), 2, RoundingMode.HALF_UP);
        return total;
    }

    /**
     * 辅助方法，用于安全地累加，避免空指针异常
     *
     * @param accumulator 累加器
     * @param value       要累加的值
     * @return 累加后的值
     */
    private BigDecimal safeAdd(BigDecimal accumulator, BigDecimal value) {
        return (value != null) ? accumulator.add(value) : accumulator;
    }

    @Override
    public ResponseInfo getNumberQery(String slipNo, String lotNo, String style) {
        /*找出数量*/
        List<PcSupplementSizeDto> dtos = sizeMapper.getNumberDetail(slipNo, lotNo, style);
        return ResponseInfo.ok(dtos);
    }

    @Override
    public ResponseInfo spHeadUpdate(String slipNo, String slipType) {
        /*判断*/
        PcSupplementHead head = lambdaQuery()
                .eq(PcSupplementHead::getSlipNo, slipNo).one();
        if (head == null || head.getSlipNo() == null || head.getSlipNo().isEmpty()) {
            log.error("异常请求：spHeadUpdate\n错误原因：没有找到数据\n表名：PC_SUPPLEMENT_HEAD\n数据：SLIP_NO = {}", slipNo);
            return ResponseInfo.error("没有找到数据，请联系后台管理", DATA_IS_EMPTY.getCode());
        }
        if (Objects.equals(head.getPrnFlag(), Y)) {
            return ResponseInfo.error("已经打印，不能修改", INPUT_ERROR.getCode());
        }
        /*更新数据*/
        lambdaUpdate().eq(PcSupplementHead::getSlipNo, slipNo)
                .set(PcSupplementHead::getBlFlag, SlipTypeEnum.SlipTypeFind(slipType)).update();
        return ResponseInfo.ok("更新完成");
    }

    @Override
    public ResponseInfo dutyDetailDelete(DutyDtRequest request) {
        String companyId = UserIdThread.get().getCompanyId();
        /*已打印不能删除*/
        LambdaQueryWrapper<PcSupplementHead> wrapper = new LambdaQueryWrapper<PcSupplementHead>()
                .eq(PcSupplementHead::getCompanyId, companyId)
                .eq(PcSupplementHead::getSlipNo, request.getSlipNo())
                .last("LIMIT 1");
        String prnFlag = headMapper.selectOne(wrapper).getPrnFlag();
        if (Y.equals(prnFlag)) {
            return ResponseInfo.error("已打印，不能删除");
        }
        /*删除数据*/
        dutyMapper.dutyDetailDelete(request);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo getSpDetailDelete(String slipNo, String lotNo, String seqNo) {
        String companyId = UserIdThread.get().getCompanyId();
        /*校验*/
        LambdaQueryWrapper<PcSupplementHead> wrapper = new LambdaQueryWrapper<PcSupplementHead>()
                .eq(PcSupplementHead::getSlipNo,slipNo)
                        .eq(PcSupplementHead::getCompanyId,companyId);
        PcSupplementHead head = headMapper.selectOne(wrapper);
        if (head == null){
            throw new ServiceErrorException("数据异常：订单号不存在");
        }
        if (Y.equals(head.getPrnFlag())){
            throw new ServiceErrorException("已打印，请选择作废处理");
        }
        //MS TODO 2024/12/18 :  优化逻辑
        /*获取受影响材料*/

        /*按照材料原本分配占比重新计算责任数量*/

        /*删除数据*/
        detailMapper.getSpDetailDelete(slipNo, lotNo , seqNo);
        sizeMapper.getSpDetailDelete(slipNo, lotNo);
        /*重新生成材料需求*/
        spMtlAdd(slipNo);
        /*暂时删掉关联数据重新生成*/
        dutyMapper.spDetDelete(slipNo,companyId);
        return ResponseInfo.ok("请重新分配补制数量");
    }

    @Override
    public ResponseInfo dutyFileDelete(DutyAddSub request, Integer type) {
        String companyId = UserIdThread.get().getCompanyId();
        String userName = UserIdThread.get().getUserName();
        /*删除数据*/
        switch (type) {
            case 1:
                dTemp3Mapper.dutyFileDelete(request, userName);
                break;
            case 2:
                dTempMapper.dutyFileDelete(request, userName);
                break;
            default:
                break;
        }
        return ResponseInfo.ok();
    }

    @Override
    public void dutyDetailClear(Integer type) {
        String userName = UserIdThread.get().getUserName();
        String companyId = UserIdThread.get().getCompanyId();
        switch (type){
            case 0:
                LambdaQueryWrapper<PcSupplementDutyTemp3> temp3Wrapper = new LambdaQueryWrapper<PcSupplementDutyTemp3>()
                        .eq(PcSupplementDutyTemp3::getSysUser,userName)
                        .eq(PcSupplementDutyTemp3::getCompanyId, companyId);
                dTemp3Mapper.delete(temp3Wrapper);
                break;
            case 1:
                LambdaQueryWrapper<PcSupplementDutyTemp> tempWrapper = new LambdaQueryWrapper<PcSupplementDutyTemp>()
                        .eq(PcSupplementDutyTemp::getSysUser,userName)
                        .eq(PcSupplementDutyTemp::getCompanyId, companyId);
                dTempMapper.delete(tempWrapper);
                break;
            default:
                throw new InDataException("类型错误");
        }

    }

    @Override
    public void invalid(String slipNo, String invFlag) {
        String companyId = UserIdThread.get().getCompanyId();
        // 校验是否符合作废标准
        if (Y.equals(invFlag)) {
            LambdaQueryWrapper<PcSupplementHead> wrapper = new LambdaQueryWrapper<PcSupplementHead>()
                    .eq(PcSupplementHead::getSlipNo, slipNo)
                    .eq(PcSupplementHead::getCompanyId, companyId);
            PcSupplementHead head = headMapper.selectOne(wrapper);
            if (head == null){
                throw new ServiceErrorException("数据异常：未查询到该单号");
            }
            if (Y.equals(head.getCfmFlag())) {
                throw new ServiceErrorException("该单号已转审核，不能作废");
            }
            if (Y.equals(head.getPrnFlag())) {
                return;
            }
        }

        // 数据更新
        LambdaUpdateWrapper<PcSupplementHead> wrapper = new LambdaUpdateWrapper<PcSupplementHead>()
                .eq(PcSupplementHead::getSlipNo, slipNo)
                .eq(PcSupplementHead::getCompanyId, companyId)
                .set(PcSupplementHead::getInvFlag, invFlag);
        headMapper.update(null, wrapper);
    }

    /**
     * 检核是否分配责任数量
     *
     * @param slipNo    订单号
     * @param companyId 公司ID
     */
    private void dutyCheck(String slipNo, String companyId) {

        /*判断数据是否完成计算*/
        LambdaQueryWrapper<PcSupplementMtl> wrapper = new LambdaQueryWrapper<PcSupplementMtl>()
                .eq(PcSupplementMtl::getCompanyId, companyId)
                .eq(PcSupplementMtl::getSlipNo, slipNo);
        List<PcSupplementMtl> mtls = mtlMapper.selectList(wrapper);
        if (ArrayUtils.isEmpyt(mtls)) {
            throw new ServiceErrorException("请先【计算补料明细】");
        }
        /*判断责任用量是否分配*/
        LambdaQueryWrapper<PcSupplementDuty> dutyWrapper = new LambdaQueryWrapper<PcSupplementDuty>()
                .eq(PcSupplementDuty::getCompanyId, companyId)
                .eq(PcSupplementDuty::getSlipNo, slipNo);
        List<PcSupplementDuty> dutys = dutyMapper.selectList(dutyWrapper);
        if (ArrayUtils.isEmpyt(dutys)) {
            throw new ServiceErrorException("请先分配责任数量");
        }
        Map<String, BigDecimal> dutyQtyMap = dutys.stream().collect(Collectors.toMap(PcSupplementDuty::getMtlNo, PcSupplementDuty::getDutyQty, BigDecimal::add));
        for (PcSupplementMtl mtl : mtls) {
            BigDecimal dutyQty = dutyQtyMap.get(mtl.getMtlNo());
            if (dutyQty == null || dutyQty.compareTo(mtl.getActQty1())<0) {
                log.info("{},{}",dutyQty,mtl.getActQty1());
                throw new ServiceErrorException("责任数量未分配完全：缺失物料【" + mtl.getMtlName() + "】");
            }
        }
    }

    /**
     * 补单更新前检查
     * @param slipNo 订单号
     */
    private void slipUpCheck(String slipNo, String companyId) {
        LambdaQueryWrapper<PcSupplementHead> wrapper = new LambdaQueryWrapper<PcSupplementHead>()
                .eq(PcSupplementHead::getSlipNo, slipNo)
                .eq(PcSupplementHead::getCompanyId, companyId);
        List<PcSupplementHead> headList = headMapper.selectList(wrapper);
        if (ArrayUtils.isEmpyt(headList)) {
            log.error("\n错误接口：spDetailCopyUpdate\n错误原因：不存在的补单单号：{} \n相关表【PC_SUPPLEMENT_HEAD】", slipNo);
            throw new ServiceErrorException("数据异常");
        }if (headList.size() > 1) {
            log.error("\n错误接口：spDetailCopyUpdate\n错误原因：重复的补单单号：{} \n相关表【PC_SUPPLEMENT_HEAD】", slipNo);
            throw new ServiceErrorException("存在多组相同补单单号");
        }if (Y.equals(headList.get(0).getPrnFlag())) {
            throw new ServiceErrorException("已打印不能修改");
        }
    }

}
